import random
from app import db
from app.models.monthly_competition import MonthlyCompetitionSignup
from app.models.monthly_competition_match import MonthlyCompetitionMatch
from app.models.table import Table

class MonthlyCompetitionScheduleGenerator:
    @staticmethod
    def generate_schedule(competition_id, group, max_group_size=6):
        # 获取该组所有报名学员
        signups = MonthlyCompetitionSignup.query.filter_by(competition_id=competition_id, group=group).all()
        player_ids = [s.student_id for s in signups]
        n = len(player_ids)
        tables = Table.query.all()
        table_ids = [t.id for t in tables]
        random.shuffle(table_ids)
        matches = []
        if n == 0:
            return []
        if n <= max_group_size:
            # 全循环赛程生成
            rounds = n if n % 2 == 1 else n - 1
            players = player_ids.copy()
            if n % 2 == 1:
                players.append(None)  # 奇数补空
            for r in range(rounds):
                round_matches = []
                for i in range(n // 2):
                    a = players[i]
                    b = players[-i-1]
                    if a and b:
                        table_id = table_ids[(r * (n // 2) + i) % len(table_ids)]
                        match = MonthlyCompetitionMatch(
                            competition_id=competition_id,
                            group=group,
                            round=r+1,
                            player_a_id=a,
                            player_b_id=b,
                            table_id=table_id
                        )
                        db.session.add(match)
                        round_matches.append(match)
                # 轮换
                players = [players[0]] + [players[-1]] + players[1:-1]
                matches.extend(round_matches)
        else:
            # 超过max_group_size，分小组，每组全循环，取前两名交叉淘汰（此处只生成小组赛程）
            num_subgroups = (n + max_group_size - 1) // max_group_size
            subgroups = [player_ids[i*max_group_size:(i+1)*max_group_size] for i in range(num_subgroups)]
            for idx, subgroup in enumerate(subgroups):
                rounds = len(subgroup) if len(subgroup) % 2 == 1 else len(subgroup) - 1
                players = subgroup.copy()
                if len(subgroup) % 2 == 1:
                    players.append(None)
                for r in range(rounds):
                    for i in range(len(subgroup) // 2):
                        a = players[i]
                        b = players[-i-1]
                        if a and b:
                            table_id = table_ids[(r * (len(subgroup) // 2) + i) % len(table_ids)]
                            match = MonthlyCompetitionMatch(
                                competition_id=competition_id,
                                group=group,
                                subgroup=idx+1,
                                round=r+1,
                                player_a_id=a,
                                player_b_id=b,
                                table_id=table_id
                            )
                            db.session.add(match)
                    players = [players[0]] + [players[-1]] + players[1:-1]
        db.session.commit()
        return True
